package tc.alert.tckejisoc.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.PutMappingRequest;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermsQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.stereotype.Component;
import tc.alert.tckejisoc.dto.EdrDTO;
import tc.alert.tckejisoc.eum.AttackTypeEum;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Component
public class EsUtils {


    public static void deleteEsIndex(RestHighLevelClient client, String index) throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest(index);
        client.indices().delete(request, RequestOptions.DEFAULT);
    }

    public void createIndex(RestHighLevelClient client, String index) throws IOException {

        CreateIndexRequest request = new CreateIndexRequest(index);
        client.indices().create(request, RequestOptions.DEFAULT);
    }

    public void putMapping(RestHighLevelClient client, String mapping) throws IOException {
        PutMappingRequest request = new PutMappingRequest(mapping);

        client.indices().putMapping(request, RequestOptions.DEFAULT);
    }

    public static List<EdrDTO> regxWaf(RestHighLevelClient client, String str) throws IOException {
        List<String> eventIds = new ArrayList<>();
        List<EdrDTO> wafDTOs = new ArrayList<>();


        // 定义正则表达式
        String regex = "\\\\\"event_id\\\\\":\\\\\"([^\"]+)\\\\\",";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);

        // 查找所有匹配项
        while (matcher.find()) {
            String eventId = matcher.group(1); // 捕获组中的内容
            eventIds.add(eventId);
        }


        // 创建 TermsQueryBuilder
        TermsQueryBuilder termsQuery = QueryBuilders.termsQuery("event_id", eventIds);

        // 在 SearchSourceBuilder 中使用
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(termsQuery);
        SearchRequest searchRequest = new SearchRequest("event-waf*");
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//        SearchHit[] hits = searchResponse.getHits().getHits();
        SearchHits hits = searchResponse.getHits();

        for (SearchHit hit : hits) {
            String index = hit.getIndex();
            Map<String, Object> source = hit.getSourceAsMap();
            EdrDTO dto = new EdrDTO();
            dto.setIndex(index);
            String attack_type = safeGet(source, "attack_type");
            AttackTypeEum attackTypeEum = AttackTypeEum.fromTypeCode(attack_type);
            dto.setEventName(attackTypeEum.getChineseName());
            String req_attack_type = safeGet(source, "req_attack_type");
            AttackTypeEum reqattackTypeEum = AttackTypeEum.fromTypeCode(req_attack_type);
            dto.setReqAttackType(reqattackTypeEum.getChineseName());
            String rsq_attack_type = safeGet(source, "rsp_attack_type");
            AttackTypeEum rspattackTypeEum = AttackTypeEum.fromTypeCode(rsq_attack_type);
            dto.setRespAttackType(rspattackTypeEum.getChineseName());
            dto.setSrcIp(safeGet(source, "src_ip"));
            dto.setDestIp(safeGet(source, "dest_ip"));
            dto.setTimestampHuman(safeGet(source, "timestamp_human"));
            dto.setId(safeGet(source, "event_id"));
            dto.setAction(safeGet(source, "action"));
            //装配实体
            wafDTOs.add(dto);

            log.debug(dto.toString());
        }

        return wafDTOs;
    }


    public static List<EdrDTO> regxEdr(RestHighLevelClient client, String str) throws IOException {
        List<String> eventIds = new ArrayList<>();
        List<EdrDTO> edrDTOS = new ArrayList<>();
        // 定义正则表达式
        String regex = "\\\\\"_id\\\\\":\\\\\"([^\"]+)\\\\\",";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);

        // 查找所有匹配项
        while (matcher.find()) {
            String eventId = matcher.group(1); // 捕获组中的内容
            eventIds.add(eventId);
        }


        // 创建 TermsQueryBuilder
        TermsQueryBuilder termsQuery = QueryBuilders.termsQuery("_id", eventIds);

        // 在 SearchSourceBuilder 中使用
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(termsQuery);
        SearchRequest searchRequest = new SearchRequest("event-edr*");
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//        SearchHit[] hits = searchResponse.getHits().getHits();
        SearchHits hits = searchResponse.getHits();
        System.out.println("总命中数: " + hits.getTotalHits().value);
        for (SearchHit hit : hits) {
            String index = hit.getIndex();
            String id = hit.getId();
            Map<String, Object> source = hit.getSourceAsMap();
            EdrDTO edrDTO = new EdrDTO();
            edrDTO.setEventName(safeGet(source, "event_name"));
            edrDTO.setEventLevel(safeGet(source, "event_level"));
            edrDTO.setIndex(index);
            edrDTO.setRegion(safeGet(source, "region"));
            edrDTO.setEventContent(safeGet(source, "event_content"));
//            String s = safeGet(source, "@timestamp");
//
//            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//            String formattedDate = sdf.format(new Date());
//            edrDTO.setDataTime(formattedDate);
            edrDTO.setId(id);
            edrDTO.setSrcIp(safeGet(source, "src_ip"));
            edrDTO.setAgentIp(safeGet(source, "agent_ip"));
            edrDTO.setMassage(safeGet(source, "message"));
            //装配实体
            edrDTOS.add(edrDTO);

            log.debug(edrDTO.toString());
        }

        return edrDTOS;
    }

    public static List<EdrDTO> regxTy(RestHighLevelClient client, String str) throws IOException {
        List<String> eventIds = new ArrayList<>();
        List<EdrDTO> edrDTOS = new ArrayList<>();
        // 定义正则表达式
        String regex = "\\\\\"_id\\\\\":\\\\\"([^\"]+)\\\\\",";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);

        // 查找所有匹配项
        while (matcher.find()) {
            String eventId = matcher.group(1); // 捕获组中的内容
            eventIds.add(eventId);
        }


        // 创建 TermsQueryBuilder
        TermsQueryBuilder termsQuery = QueryBuilders.termsQuery("_id", eventIds);

        // 在 SearchSourceBuilder 中使用
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(termsQuery);
        SearchRequest searchRequest = new SearchRequest("event-ty*");
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//        SearchHit[] hits = searchResponse.getHits().getHits();
        SearchHits hits = searchResponse.getHits();

        System.out.println("总命中数: " + hits.getTotalHits().value);
        for (SearchHit hit : hits) {
            String index = hit.getIndex();
            String id = hit.getId();


            //sandbox_mail|  邮件威胁  sip 发件ip
            //alarm 告警   alarm_sip 受害IP  attack_sip 攻击ip
            // webids-webattack_dolog  sip 源ip  dip 目的ip
            String srcip = "attack_sip";
            String destip = "alarm_sip";
//            String srcip="";
            Map<String, Object> source = hit.getSourceAsMap();
            //根据日志名称 组装不同信息体
            if (null != source.get("syslog_module") && source.get("syslog_module").toString().contains("_dolog")) {
                srcip = "sip";
                destip = "dip";
            }
            EdrDTO edrDTO = new EdrDTO();
            edrDTO.setEventName(safeGet(source, "attack_type"));
            if (null != source.get("attack")) {
                Map<String, Object> oas = (Map<String, Object>) source.get("attack");
                edrDTO.setSrcIp(safeGet(oas, srcip));
                edrDTO.setDestIp(safeGet(oas, destip));

            }
            edrDTO.setIndex(index);
            edrDTO.setDataTime(safeGet(source, "access_time"));
            edrDTO.setId(id);


            //装配实体
            edrDTOS.add(edrDTO);

            log.debug(edrDTO.toString());
        }

        return edrDTOS;
    }

    public static List<EdrDTO> regxHr(RestHighLevelClient client, String str) throws IOException {
        List<String> eventIds = new ArrayList<>();
        List<EdrDTO> edrDTOS = new ArrayList<>();
        // 定义正则表达式
        String regex = "\\\\\"_id\\\\\":\\\\\"([^\"]+)\\\\\",";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);

        // 查找所有匹配项
        while (matcher.find()) {
            String eventId = matcher.group(1); // 捕获组中的内容
            eventIds.add(eventId);
        }


        // 创建 TermsQueryBuilder
        TermsQueryBuilder termsQuery = QueryBuilders.termsQuery("_id", eventIds);

        // 在 SearchSourceBuilder 中使用
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(termsQuery);
        SearchRequest searchRequest = new SearchRequest("event-hr*");
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//        SearchHit[] hits = searchResponse.getHits().getHits();
        SearchHits hits = searchResponse.getHits();

        System.out.println("总命中数: " + hits.getTotalHits().value);
        for (SearchHit hit : hits) {
            String index = hit.getIndex();
            String id = hit.getId();
            Map<String, Object> source = hit.getSourceAsMap();

            EdrDTO edrDTO = new EdrDTO();
            edrDTO.setDataTime(safeGet(source, "syslog_timestamp"));
            edrDTO.setEventName(safeGet(source, "event_type"));
            Object o = source.get("event");
/**
 * ​ client_id - 终端ID
 * ​ client_name - 终端名称
 * ​ gid - 分组ID
 * ​ group_name - 终端分组
 * ​ ip_addr - 本地IP
 * ​ call_ip - 通信IP
 * ​ mac - 终端MAC地址
 * ​ uptm - 时间戳
 * ​ event_type - 事件类型
 */
            if (null != o) {
                Map<String, Object> oas = (Map<String, Object>) source.get("event");
                edrDTO.setDataTime(safeGet(source, "syslog_timestamp"));
                edrDTO.setEventName(safeGet(oas, "event_type"));
                Map<String, Object> event = (Map<String, Object>) oas.get("event");
                if (StringUtils.isNoneBlank(safeGet(event, "result_view"))) {
                    edrDTO.setAction(safeGet(event, "result_view"));
                } else if (StringUtils.isNoneBlank(safeGet(event, "blocked"))) {
                    edrDTO.setAction(safeGet(event, "blocked"));
                } else {
                    edrDTO.setAction(safeGet(event, "result"));
                }
                edrDTO.setSrcIp(safeGet(event, "call_ip"));//通信ip
                edrDTO.setDestIp(safeGet(event, "ip_addr"));//本地ip
                edrDTO.setMac(safeGet(event, "mac"));
                edrDTO.setProtocol(safeGet(event, "protocol"));
            }
            edrDTO.setIndex(index);

            edrDTO.setId(id);


            //装配实体
            edrDTOS.add(edrDTO);

            log.debug(edrDTO.toString());
        }

        return edrDTOS;
    }

    private static String safeGet(Map<String, Object> source, String key) {
        Object value = source.get(key);
        return value != null ? value.toString() : "";
    }

    /**
     * 自动生成索引
     *
     * @param index
     * @return
     * @throws IOException
     */
    public static boolean isIndexExists(RestHighLevelClient client, String index) throws IOException {
        GetIndexRequest request = new GetIndexRequest(index);

        // 检查索引是否存在
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        if (!exists) {
            return false;
        }
        return true;
    }
    public static String getindex(String index) {
        DateTime now = new DateTime();
        DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
        String formattedDate = now.toString(formatter);
        index = index + formattedDate;

        return index;
    }}
